package com.gitee.yongzhuzl.commonutil.util.ip;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

/**
 * description: 获取客户端IP和服务器IP工具类
 * @author 朱正磊
 * @date 2019-07-17 16:15:51
 */
public class IpUtil {

    private static final Logger log = LoggerFactory.getLogger(IpUtil.class);

    /**
     * 获取服务器IP地址方式一
     * description：获取本机的IP地址
     * user 朱正磊
     * time 2019-07-18 22:32
     * @return 返回本机的IP地址
     */
    public static String getServerIp() {
        try {
            InetAddress address = InetAddress.getLocalHost();
            // 返回IP地址
            return address.getHostAddress();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取服务器IP地址方式二
     * description：获取本地IP地址
     * user 朱正磊
     * time 2019-07-18 22:30
     * @return 返回本地IP地址
     */
    public static String queryServerIp() {
        try {
            String ipString = "";
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    ip = addresses.nextElement();
                    if (ip instanceof Inet4Address && !"127.0.0.1".equals(ip.getHostAddress())) {
                        return ip.getHostAddress();
                    }
                }
            }
            return ipString;
        } catch (SocketException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取服务器IP地址方式三
     * description：获取本机IP地址
     * user 朱正磊
     * time 2019-07-18 22:12
     * @return 返回本机IP地址
     */
    public static String findServerIp() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress ip = addresses.nextElement();
                    if (ip instanceof Inet4Address
                            && !ip.isLoopbackAddress() //loopback地址即本机地址，IPv4的loopback范围是127.0.0.0 ~ 127.255.255.255
                            && !ip.getHostAddress().contains(":")) {
                        log.info("本机的IP = {}", ip.getHostAddress());
                        return ip.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取客户端IP地址方式一
     * description: 获取客户端IP地址
     * @author 朱正磊
     * @date 2019-07-17 16:24:23
     * @param request 请求对象
     * @return 返回客户端IP地址
     */
    public static String getClientIp(HttpServletRequest request) {
        String unknown = "unknown";
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !unknown.equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !unknown.equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getRemoteAddr();
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (Exception e) {
                log.error("获取客户端IP地址异常：", e);
            }
        }
        // 如果是IPv6地址，则转换成IPv4地址
        if (ip != null && ip.contains(":")) {
            ip = convertIPv6ToIPv4(ip);
        }
        return ip;
    }

    /**
     * 获取客户端IP地址方式二
     * description：获取客户端IP地址
     * user 朱正磊
     * time 2019-07-18 22:48
     * @param request 请求对象
     * @return 返回客户端IP地址
     */
    public static String queryClientIp(HttpServletRequest request) {
        String unknown = "unknown";
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        // 获取客户端IP地址
        ip = getIpAddress(ip, unknown, request);
        // 如果是IPv6地址，则转换成IPv4地址
        if (ip != null && ip.contains(":")) {
            ip = convertIPv6ToIPv4(ip);
        }
        return ip;
    }

    /**
     * 获取客户端IP地址方式三
     * description：获取客户端IP地址
     * user 朱正磊
     * time 2019-07-18 22:49
     * @param request 请求对象
     * @return 返回客户端IP地址
     */
    public static String findClientIp(HttpServletRequest request) {
        String unknown = "unknown";
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        // 获取客户端IP地址
        ip = getIpAddress(ip, unknown, request);
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        // 如果是IPv6地址，则转换成IPv4地址
        if (ip != null && ip.contains(":")) {
            ip = convertIPv6ToIPv4(ip);
        }
        return ip;
    }

    /**
     * description: 将IPv6地址转换成IPv4地址
     * @author 朱正磊
     * @date 2024-07-11 10:39:13
     * @param ipv6Address IPv6地址
     * @return 返回IPv4地址
     */
    public static String convertIPv6ToIPv4(String ipv6Address) {
        if (ipv6Address == null) {
            return null;
        }
        String[] parts = ipv6Address.split(":");
        if (parts.length != 8) {
            return null;
        }
        return Integer.parseInt(parts[6].substring(0, 2), 16) + "." +
                Integer.parseInt(parts[6].substring(2, 4), 16) + "." +
                Integer.parseInt(parts[7].substring(0, 2), 16) + "." +
                Integer.parseInt(parts[7].substring(2, 4), 16);
    }

    /**
     * description: 获取客户端IP地址
     * @author 朱正磊
     * @date 2025-09-04 13:07:04
     * @param ip ip地址
     * @param unknown 未知字符串
     * @param request http请求
     * @return 返回IP地址
     */
    public static String getIpAddress(String ip, String unknown, HttpServletRequest request) {
        if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if ("0:0:0:0:0:0:0:1".equals(ip)) {
                try {
                    ip = InetAddress.getLocalHost().getHostAddress();
                } catch (Exception e) {
                    log.error("获取客户端IP地址异常：", e);
                }
            }
        }
        return ip;
    }

}
